home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / hypercrd / xcmd / sprtxtrn.sea / Support Tools eXternals 1.2.5 / card_36250.txt < prev    next >
Text File  |  1990-11-13  |  16KB  |  491 lines

  1. -- card: 36250 from stack: in.5
  2. -- bmap block id: 42871
  3. -- flags: 0000
  4. -- background id: 3858
  5. -- name: INITList
  6. ----- HyperTalk script -----
  7. on CloseCard
  8.   put empty into cd fld "INIT list"
  9.   set the scroll of cd fld "INIT list" to 0
  10.   pass CloseCard
  11. end CloseCard
  12.  
  13. on HideObjects
  14.   hide cd fld "INIT list"
  15.   hide cd btn "ΓÇ£DetailedΓÇ¥"
  16.   hide cd btn "All files reported"
  17. end HideObjects
  18.  
  19. on ShowObjects
  20.   show cd fld "INIT list"
  21.   show cd btn "ΓÇ£DetailedΓÇ¥"
  22.   show cd btn "All files reported"
  23. end ShowObjects
  24.  
  25.  
  26. -- part 1 (field)
  27. -- low flags: 00
  28. -- high flags: 0007
  29. -- rect: left=19 top=117 right=288 bottom=236
  30. -- title width / last selected line: 0
  31. -- icon id / first selected line: 0 / 0
  32. -- text alignment: 0
  33. -- font id: 4
  34. -- text size: 9
  35. -- style flags: 0
  36. -- line height: 12
  37. -- part name: INIT list
  38.  
  39.  
  40. -- part 2 (button)
  41. -- low flags: 00
  42. -- high flags: A002
  43. -- rect: left=22 top=292 right=326 bottom=125
  44. -- title width / last selected line: 0
  45. -- icon id / first selected line: 0 / 0
  46. -- text alignment: 1
  47. -- font id: 0
  48. -- text size: 12
  49. -- style flags: 8192
  50. -- line height: 16
  51. -- part name: ╥Detailed╙
  52. ----- HyperTalk script -----
  53. on mouseUp
  54.   global errGlobal
  55.   set cursor to watch
  56.   put INITList("Detailed", "noDialog:errGlobal") into INITInfo
  57.   if errGlobal Γëá empty then
  58.     answer "Error: ΓÇ£" & errGlobal & "ΓÇ¥"
  59.     put empty into errGlobal
  60.   else
  61.     put INITInfo into cd fld "init list"
  62.   end if
  63. end mouseUp
  64.  
  65.  
  66.  
  67.  
  68. -- part 4 (button)
  69. -- low flags: 00
  70. -- high flags: A002
  71. -- rect: left=130 top=292 right=326 bottom=233
  72. -- title width / last selected line: 0
  73. -- icon id / first selected line: 0 / 0
  74. -- text alignment: 1
  75. -- font id: 0
  76. -- text size: 12
  77. -- style flags: 8192
  78. -- line height: 16
  79. -- part name: All Files Reported
  80. ----- HyperTalk script -----
  81. on mouseUp
  82.   global errGlobal
  83.   set cursor to watch
  84.   put INITList("", "noDialog:errGlobal") into INITInfo
  85.   if errGlobal Γëá empty then
  86.     answer "Error: ΓÇ£" & errGlobal & "ΓÇ¥"
  87.     put empty into errGlobal
  88.   else
  89.     put INITInfo into cd fld "init list"
  90.   end if
  91. end mouseUp
  92.  
  93.  
  94.  
  95.  
  96. -- part contents for background part 38
  97. ----- text -----
  98. 26/50
  99.  
  100. -- part contents for background part 20
  101. ----- text -----
  102.      An XFCN which scans the System Folder of the system startup volume for files of type 'INIT' and 'RDEV' and 'cdev' and returns the names of all files in a carraige return delimited list.  All control characters in file names (ASCII value less than 32) are represented by period ('.'). 
  103.  
  104.      If nothing is passed as the first parameter, all files of these types will be listed.  If the literal string ΓÇ£DETAILEDΓÇ¥ is passed as the first parameter, each file will be opened to see if it contains a resource of type INIT .  In this case, the file name will not be returned unless an INIT resource is found.  Opening all files will take longer. On my system ΓÇ£DETAILEDΓÇ¥ takes 30 ticks to report 19 files, compared with 10 ticks to list 29 files (Mac IIx).
  105.  
  106.      Calling syntax : INITList(<ΓÇ£DetailedΓÇ¥, <ΓÇ£noDialog:ΓÇ¥errGlobal>)
  107.   DETAILED: open all files to make sure that they contain a resource of type INIT.
  108.  
  109. NOTE: The list of INITs reported by this XFCN may not exactly represent the list of INITs actually run at startup time on systems which use one of the INITs which change the order of INIT loading without changing file type ie. ΓÇ£INITPickerΓÇ¥, ΓÇ£INITHoundΓÇ¥, etc.   In such a case the list may contain the names of more files than actually ran at startup.
  110.  
  111.  
  112. -- part contents for background part 42
  113. ----- text -----
  114. unit INITFinder;
  115. {}
  116. { At startup the system scans the System Folder of the system}
  117. { startup volume for files of type 'INIT' and 'RDEV'.  When it finds }
  118. { it opens the file and calls all resources of type 'INIT'.  We mimic }
  119. { this process, but just return the names of all files. }
  120. {}
  121. {  brought to you by:  Anup Murarka      Eric Carlson    }
  122. {            ALINK:  SKEPTIC      ALINK:  cyNic  }
  123. {                  CIS:  76004,3356    }
  124. {}
  125. {        We are part of the Support Tools Development Group,  }
  126. {        Apple Computer, Inc.   }
  127. {}
  128. {        please DO NOT contack Mac DTS for support of this code!  }
  129. {}
  130. {        please DO contact the authors for support of this code!  }
  131. {}
  132. {        Send comments, bug reports, requests to any of the above  }
  133. {        E-mail addresses or to:}
  134. {}
  135. {              (one of us)          }
  136. {              Apple Computer, Inc.     }
  137. {              900 E. Hamilton, Ave.    }
  138. {              Campbell, CA   95008    }
  139. {              M/S 72-L          }
  140. {}
  141. {  Copyright:  ┬⌐ 1989, 1990 by Apple Computer, Inc., all rights reserved.  }
  142. {}
  143. { written by Eric Carlson                    }
  144. { AppleLink:  cyNic                        }
  145. { modification history                      }
  146. {       Date        Initials                  Comments              }
  147. {       ----        ------  ------------------------------------------------------}
  148. {    8/16/89      ec       first written                            }
  149. {    2/18/90      ec      modified to build handle rather than str255 with names, avoid}
  150. {                    overflow for large init lists  }
  151. {}
  152.  
  153. interface
  154.   uses
  155.     HyperXCMD;
  156.  
  157.   procedure main (paramPtr: XCmdPtr);
  158.  
  159. implementation
  160.  
  161.   procedure reportToUser (paramPtr: XCmdPtr;
  162.                   msgStr: str255);
  163. {}
  164. { report something back to the user.  }
  165. { the last parameter (optional) to an external may contain }
  166.  { "noDialog" or "noDialog:GlobalName".  GlobalName is the name }
  167.  { of a HyperTalk global variable into which error messages will be }
  168.  { placed.  we've decided to use this approach to avoid confusing }
  169. { an error message with a valid result being returned from an XFCN. }
  170. {}
  171.     var
  172.       tempStr: str255;
  173.   begin
  174. {check the last param to see if the user requested that}
  175. { we suppress the error dialog }
  176.     ZeroToPas(paramPtr, paramPtr^.params[paramPtr^.paramCount]^, tempStr);
  177.     UprString(tempStr, true);
  178.     if pos('NODIALOG', tempStr) = 0 then
  179.   { no special error handling specified, throw up a dialog and return the error message }
  180.       begin
  181.         SendCardMessage(paramPtr, concat('answer "', msgStr, '"'));
  182.         paramPtr^.returnValue := PasToZero(paramPtr, msgStr);
  183.       end
  184.     else if (pos(':', tempStr) > 0) then
  185.   { requested global AND noDialog so we fill in the global and return empty }
  186.       begin
  187.         tempStr := copy(tempStr, pos(':', tempStr) + 1, length(tempStr));
  188.                             { get the name of the HC global  to fill }
  189.         SetGlobal(paramPtr, tempStr, PasToZero(paramPtr, msgStr));
  190.                             { and fill it }
  191.         paramPtr^.returnValue := PasToZero(paramPtr, '');  { return empty }
  192.       end
  193.     else
  194.   { requested noDialog only so we return the error condition as the result }
  195.       paramPtr^.returnValue := PasToZero(paramPtr, msgStr);
  196.   end;  { procedure }
  197.  
  198.   function AskedForHelp (paramPtr: XCmdPtr;
  199.                   syntaxMsg: Str255;
  200.                   copyrightMsg: Str255): boolean;
  201. {  check to see if the user sent a '?' or a '!' as }
  202. { the only parameter. if so we will respond with }
  203. { the calling syntax or the copyright/version info }
  204. { for this external }
  205. {}
  206.     var
  207.       firstStr: str255;
  208.   begin
  209.     askedForHelp := false;
  210.     if paramPtr^.paramCount = 1 then
  211.       begin
  212.         ZeroToPas(paramPtr, paramPtr^.params[1]^, firstStr);
  213.           { what is the first param? }
  214.         if firstStr = '?' then
  215.           begin
  216.             reportToUser(paramPtr, syntaxMsg);
  217.             askedForHelp := true
  218.           end  { asked for help }
  219.         else if firstStr = '!' then
  220.           begin
  221.             reportToUser(paramPtr, copyRightMsg);
  222.             askedForHelp := true
  223.           end;  { asked for copyright info }
  224.       end;  { one parameter passed }
  225.   end;  { function }
  226.  
  227.   function NumberToString (paramPtr: XCmdPtr;
  228.                   num: LONGINT): Str255;
  229. { use the toolbox call rather than HC's }
  230.     var
  231.       tempStr: str255;
  232.   begin
  233.     NumToString(num, tempStr);
  234.     NumberToString := tempStr;
  235.   end;
  236.  
  237.   procedure reportResError (var paramPtr: XCmdPtr;
  238.                   errorNum: integer);
  239.     var
  240.       errMsg, tempName: str255;
  241.   begin
  242.     case errorNum of          { what caused the problem? }
  243.       -0: 
  244.         errMsg := 'no error.';
  245.       25: 
  246.         errMsg := 'out of memory.';
  247.       -36: 
  248.         errMsg := 'I/O Error.';
  249.       -37: 
  250.         errMsg := 'bad file name or volume name.';
  251.       -38: 
  252.         errMsg := 'file not open.';
  253.       -39: 
  254.         errMsg := 'that file has no resource fork.';
  255.       -42: 
  256.         errMsg := 'too many files open.';
  257.       -43: 
  258.         errMsg := 'file not found.';
  259.       -45, -54, -61: 
  260.         errMsg := 'file locked.';
  261.       -47, -49: 
  262.         errMsg := 'file is busy.';
  263.       -53: 
  264.         errMsg := 'that volume is not on line.';
  265.       -108: 
  266.         errMsg := 'not enough room in heap zone.';
  267.       -120: 
  268.         errMsg := 'directory not found.';
  269.       -121: 
  270.         errMsg := 'too many working directories open.';
  271.       -127: 
  272.         errMsg := 'internal file system error.';
  273.       -192: 
  274.         errMsg := 'resource not found.';
  275.       -193: 
  276.         errMsg := 'file not found.';
  277.       otherwise
  278.         errMsg := concat('unexpected error #', NumberToString(paramPtr, errorNum));
  279.     end;    { case }
  280.  
  281.     errMsg := concat('Sorry, ', errMsg);
  282.     reportToUser(paramPtr, errMsg);
  283.     { return the error message }
  284.   end;    { function }
  285.  
  286.   function BitTest (AddressToCheck: ptr;
  287.                   TotalBits: integer;
  288.                   BitToTest: longint): boolean;
  289.   { function that allows caller to use std. 68000 bit notation instead of the Toolbox's reversed notation}
  290.   { example:  bit 0 (the least significant bit) in a byte is bit 7 in the Toolbox's notation}
  291.   begin
  292.     BitTest := BitTst(AddressToCheck, TotalBits - 1 - BitToTest);
  293.   end;
  294.  
  295.   function AppendString (hndl: Handle;
  296.                   newStr: Str255): OSErr;
  297. {}
  298. { stick the string onto the back of the handle }
  299. {}
  300.   begin
  301.     AppendString := PtrAndHand(Ptr(ORD4(@newStr) + 1), hndl, LENGTH(newStr));
  302.   end;
  303.  
  304.   function StripControls (replacementChar: char;
  305.                   theStr: Str255): Str255;
  306. { replace all control characters in the passed string }
  307.     var
  308.       charPos: integer;
  309.   begin
  310.     for charPos := 1 to length(theStr) do
  311.       if ord(theStr[charPos]) < 32 then      { char < ascii 32? }
  312.         theStr[charPos] := replacementChar;    { yes, replace it }
  313.     StripControls := theStr;
  314.   end;
  315.  
  316.   procedure INITFinder (paramPtr: XCmdPtr);
  317.     label
  318.       10;
  319.     type
  320.       HFSBlock = record
  321.           case integer of
  322.             1: (
  323.                 HBlock: HParamBlockRec
  324.             );
  325.             2: (
  326.                 WDBlock: WDPBRec
  327.             );
  328.             3: (
  329.                 InfoBlock: CInfoPBRec
  330.             );
  331.         end;
  332.     var
  333.       ourHFSBlock: HFSBlock;
  334.       fName, detailStr, copyRtStr, syntaxStr: Str255;
  335.       sysFolder: longint;
  336.       INITCount, systemVRefNum: integer;
  337.       fileCount, index, errorCode, theRes: integer;
  338.       sysRec: SysEnvRec;
  339.       nameList: handle;
  340.       tempLong: longint;
  341.  
  342.   begin
  343.     syntaxStr := 'INITList(<ΓÇ£DetailedΓÇ¥>, <ΓÇ£noDialog:ΓÇ¥errorGlobal>)';
  344.     copyRtStr := '┬⌐ 1989 Apple Computer, Inc., v.1.1, by Eric Carlson.';
  345.  
  346.     if (askedForHelp(paramPtr, syntaxStr, copyRtStr)) then
  347.       exit(INITFinder);
  348.  
  349. { find out if we should open every file to explicitly look for INITs }
  350.     detailStr := '';
  351.     ZeroToPas(paramPtr, paramPtr^.params[1]^, detailStr);
  352.     UprString(detailStr, true);
  353.  
  354. { Get the vrefnum of the directory containing the open System file. }
  355. { We will use this in our OpenRFPerm call since we don't have (or need) }
  356. { the full path name to the system folder. }
  357.     errorCode := SysEnvirons(2, sysRec);
  358.     if errorCode <> noErr then
  359.       begin
  360.         reportResError(paramPtr, errorCode);
  361.         exit(INITFinder);
  362.       end;
  363.     systemVRefNum := sysRec.sysVRefNum;
  364.  
  365.     with ourHFSBlock.HBlock do
  366.       begin
  367.         ioCompletion := nil;
  368.         ioNamePtr := nil;
  369.         ioVRefNum := systemVRefNum;
  370.         ioVolIndex := 0;
  371.       end;
  372.  
  373.     errorCode := PBHGetVInfo(@ourHFSBlock, false);
  374.     if errorCode <> noErr then
  375.       begin
  376.         reportResError(paramPtr, errorCode);
  377.         exit(INITFinder);
  378.       end;
  379.  
  380.     SysFolder := ourHFSBlock.HBlock.ioVFndrInfo[1];
  381.  
  382.     with ourHFSBlock.WDBlock do
  383.       begin
  384.         ioWDDirID := SysFolder;
  385.         ioCompletion := nil;
  386.         ioNamePtr := nil;
  387.         ioVRefNum := systemVRefNum;
  388.       end;
  389.  
  390.     with ourHFSBlock.InfoBlock do
  391.       begin
  392.         ioCompletion := nil;
  393.         ioNamePtr := nil;
  394.         ioVRefNum := systemVRefNum;
  395.         ioFDirIndex := -1;
  396.         ioDrDirID := SysFolder;
  397.       end;
  398.  
  399.     errorCode := PBGetCatInfo(@ourHFSBlock, false);
  400.     if errorCode <> noErr then
  401.       begin
  402.         reportResError(paramPtr, errorCode);
  403.         exit(INITFinder);
  404.       end;
  405.  
  406.     nameList := NewHandle(0);
  407.     errorCode := MemError;
  408.     if errorCode <> noErr then
  409.       begin
  410.         reportResError(paramPtr, errorCode);
  411.         exit(INITFinder);
  412.       end;
  413.  
  414. {  Use PBGetCatInfo to determine the number of files and folders}
  415. {     in the System folder. }
  416.     FileCount := ourHFSBlock.InfoBlock.ioDrNmFls;
  417.     MoveHHI(nameList);                    { lock down the list }
  418.  
  419. {  Now index through the System folder, calling PBGetCatInfo for   }
  420. { each object within it.  Check the attributes to see if it is a folder.  }
  421. { If it is not, then see if the file is of type INIT, cdev, or RDEV.     }
  422. { If it is one of these types and we are supposed to be making a     }
  423. { list,  open the resource fork and look for a resource of type INIT.    }
  424. { If one is found,  report the name of the file}
  425.     for index := 1 to FileCount do
  426.       begin
  427.         fName := '';
  428.         with ourHFSBlock.InfoBlock do
  429.           begin
  430.             ioCompletion := nil;
  431.             ioNamePtr := @fName;
  432.             ioVRefNum := systemVRefNum;
  433.             ioFDirIndex := index;
  434.             ioDirID := SysFolder;
  435.           end;
  436.  
  437.         errorCode := PBGetCatInfo(@ourHFSBlock, false);
  438.         if errorCode <> noErr then
  439.           begin
  440.             reportResError(paramPtr, errorCode);
  441.             goto 10;
  442.           end;
  443.  
  444.         if not BitTest(@ourHFSBlock.InfoBlock.ioFlAttrib, 8, 4) then  { not a directory }
  445.           if (ourHFSBlock.InfoBlock.ioFlFndrInfo.fdType = 'INIT') or (ourHFSBlock.InfoBlock.ioFlFndrInfo.fdType = 'cdev') or (ourHFSBlock.InfoBlock.ioFlFndrInfo.fdType = 'RDEV') then
  446.             begin
  447.               if detailStr = 'DETAILED' then        { open every file and look for 'INIT' resources }
  448.                 begin
  449.                   TheRes := OpenRFPerm(fName, systemVRefNum, fsRdPerm);
  450.                   if ResError <> noErr then
  451.                     begin
  452.                       CloseResFile(TheRes);
  453.                       goto 10;
  454.                     end;
  455.                   INITCount := count1Resources('INIT');
  456.                   if INITCount = 0 then
  457.                     fName := '';
  458.                   CloseResFile(TheRes);
  459.                 end;    { asked to open all files }
  460.  
  461.               if fName <> '' then
  462.                 begin
  463.                   fName := StripControls('.', fName);        { replace any control chars from the file name }
  464.                   fName := concat(fName, chr(13));          { add a return and }
  465.                   errorCode := AppendString(nameList, fName);  { add the name to the list }
  466.                   if errorCode <> noErr then
  467.                     begin
  468.                       reportResError(paramPtr, errorCode);
  469.                       if nameList <> nil then
  470.                         disposHandle(nameList);
  471.                       exit(INITFinder);
  472.                     end;    { no error }
  473.                 end;    { we have a name to report }
  474.             end;    { file of type cdev, INIT, or RDEV }
  475. 10:
  476.       end;    { looping through files }
  477.     if nameList <> nil then
  478.       begin
  479.         SetHandleSize(nameList, GetHandleSize(nameList) - 1);  { drop the trailing comma }
  480.         errorCode := AppendString(nameList, chr(0));        { Terminate with 0 byte  }
  481.         if errorCode <> noErr then
  482.           reportResError(paramPtr, errorCode);
  483.       end;
  484.     paramPtr^.returnValue := nameList;
  485.   end;
  486.  
  487.   procedure main (paramPtr: XCmdPtr);
  488.   begin
  489.     INITFinder(paramPtr);
  490.   end;
  491. end.